/**
 * 74hc595.h - 串转并芯片功能封装 (头文件)
 * by Nixsawe <ziming_cool@126.com>
 * 2021-12-16 ~ 2021-12-16
 * 
 * 封装串转并芯片功能函数，以方便调用
 */

#ifndef __S2P_74HC595_H__
#define __S2P_74HC595_H__

#include<atmel/at89x52.h>
#include<intrins.h>

// 定义芯片的串行输入以及时钟引脚
#ifndef S2P_SER
#define S2P_SER P3_4
#endif

#ifndef S2P_RCLK
#define S2P_RCLK P3_5
#endif

#ifndef S2P_SRCLK
#define S2P_SRCLK P3_6
#endif

// 定义输出一位的宏，方便外部功能在中断中进行调用
#ifndef S2P_SHIFT_BIT
#define S2P_SHIFT_BIT(bit) (S2P_SER = (bit))
#endif

#ifndef S2P_WAIT_NOP
#define S2P_WAIT_NOP() do { _nop_(); _nop_(); } while(0)
#endif

#ifdef S2P_EMIT_RISING_EDGE
#undef S2P_EMIT_RISING_EDGE
#endif
#define S2P_EMIT_RISING_EDGE(CLK) do { \
	CLK = 0;	/* 切换到低电平并保持两个周期 */ \
	S2P_WAIT_NOP(); \
	CLK = 1;	/* 切换到高电平 (产生上升沿) 并保持两个周期 */ \
	S2P_WAIT_NOP(); \
} while(0)

// 定义输出移位寄存器时钟线上升沿的宏，方便外部功能在中断中进行调用
#ifndef S2P_SREDGE
#define S2P_SREDGE() S2P_EMIT_RISING_EDGE(S2P_SRCLK)
#endif

// 定义输出锁存寄存器时钟线上升沿的宏，方便外部功能在中断中进行调用
#ifndef S2P_REDGE
#define S2P_REDGE() S2P_EMIT_RISING_EDGE(S2P_RCLK)
#endif

void s2p_write_data(unsigned char dat);
void s2p_write_data_no_edge(unsigned char dat);
void s2p_set(unsigned char dat);
void s2p_clr(unsigned char dat);
void s2p_set_all();
void s2p_clr_all();
unsigned char s2p_get_last_data();
void s2p_crol_1();
void s2p_rol_1();
void s2p_crol(int n);
void s2p_cror(int n);
void s2p_rol(int n);
void s2p_ror(int n);

#endif /* __S2P_74HC595_H__ */

